package com.spc.car.service.util;

import com.spc.car.common.utils.StringUtils;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.BusFactory;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;

import javax.xml.namespace.QName;
import java.io.IOException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;

@Slf4j
@UtilityClass
public class WebserviceClientUtil {


    /*
     * CXF 动态调用Webservice，以XML传值发布数据
     * @param wsdlUrl 地址
     * @param method 方法
     * @param xmlParams 以xml参数传值
     * @return
     * @throws Exception
     */
    public static String publishData(String wsdlUrl, String method, Object xmlParams) throws Exception {
        if (StringUtils.isBlank(wsdlUrl)) {
            log.info("wsdl地址为空!");
            return null;
        }
        try {

            HttpURLConnection connection = (HttpURLConnection) new URL(wsdlUrl).openConnection();
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(30000);
            if (HttpURLConnection.HTTP_OK != connection.getResponseCode()) {
                log.info("WSDL地址不可用:{}", wsdlUrl);
            }
        } catch (IOException e) {
            log.error("WSDL地址连接{}", e);
            throw new ConnectException();
        }

        JaxWsDynamicClientFactory jaxWsDynamicClientFactory = JaxWsDynamicClientFactory.newInstance();
        Client client = jaxWsDynamicClientFactory.createClient(wsdlUrl);
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
        HTTPClientPolicy policy = new HTTPClientPolicy();
        policy.setConnectionTimeout(3000);
        policy.setReceiveTimeout(30000);
        conduit.setClient(policy);

        Endpoint endpoint = client.getEndpoint();
        String nameSpace = endpoint.getService().getName().getNamespaceURI();
        QName opName = new QName(nameSpace, method);
        BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding();
        if (bindingInfo.getOperation(opName) == null) {
            for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) {
                if (method.equals(operationInfo.getName().getLocalPart())) {
                    opName = operationInfo.getName();
                    break;
                }
            }
        }

        try {
            Object[] objects = client.invoke(opName, xmlParams);
            return objects[0].toString();
        } catch (Exception e) {
            log.error("动态调用接口异常，【地址】:{},【方法】:{},【参数】:{}", wsdlUrl, method, xmlParams, e);
        } finally {
            BusFactory.setDefaultBus(null);
            client.destroy();
        }
        return null;
    }
}
